<?php
/**
 * Created by PhpStorm.
 * User: peter
 * Date: 2018/12/7
 * Time: 7:24 PM
 */

namespace app\activity\controller;


use app\model\AccountCapitalFlow;
use app\model\ActivityOrder;
use app\model\ActivityOrderAttach;
use app\model\Bill;
use EasyWeChat\Factory;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\QrCode;
use extend\Functions;
use extend\STATUS_CODE;
use think\Controller;
use think\facade\Env;
use think\Request;

class H5 extends Controller
{
    /**
     * @purpose 支付宝支付同步回调
     * @param Request $request
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function alipaySync (Request $request) {
        // 获取订单号
        $order_no  = $request->get('out_trade_no');
        // 获取第三方支付单号
        $trade_no  = $request->get('trade_no');
        // 订单支付金额
        $total_amount = $request->get('total_amount');
        $send_pay_date = $request->get('timestamp');
        include Env::get('root_path'). 'extend/alipay/AopSdk.php';
        $aop                            = new \AopClient();
        $aop->gatewayUrl                = 'https://openapi.alipay.com/gateway.do';
        $aop->appId                     = config('alipay.app.appid');
        $aop->rsaPrivateKey             = config('alipay.app.private_key');
        $aop->format                    = "json";
        $aop->charset                   = "UTF-8";
        $aop->signType                  = "RSA";
        $aop->alipayrsaPublicKey        = config('alipay.app.public_key');
        $flag = $aop->rsaCheckV1($request->get(), null, 'RSA');
        if ($flag) {
            // 交易支付成功
            $order = new ActivityOrder();
            $order_attach = new ActivityOrderAttach();
            $order_info = $order
                ->lock(true)
                ->with(['activity' => function($query) {
                    $query->field('id,title');
                }])
                ->where([
                    'order_no' => $order_no
                ])
                ->field('id,uid,activity_id,status,order_no,pay_voucher,create_at')
                ->find();
            if (!$order_info) {
                $order->rollback();
                die();
            }
            if ($order_info->status === 99) {
                $order->rollback();
                die('<script>window.location.replace("/order/detail/'.$order_no.'")</script>');
            }

            $update_data               = [];
            $update_data['status']     = 99;
            $update_data['pay_time']   = time(); // strtotime($send_pay_date);
            $update_data['pay_money']  = $total_amount * 100;
            $update_data['pay_method'] = 3;
            $update_data['pay_no']     = $trade_no;
            // 更新订单状态
            $order
                ->isUpdate(true)
                ->save($update_data, ['id' => $order_info->id]);
            // 更新订单附表状态
            $order_attach
                ->isUpdate(true)
                ->save(['status' => 99], ['order_id' => $order_info->id, 'status' => 1]);
            // 记录账单活动支付账单
            Bill::addToBill(
                $order_info->uid,
                1,
                $order_no,
                $total_amount * 100,
                3,
                '报名活动: 【'.$order_info->activity->title.'】'
            );
            $order->commit();
            die('<script>window.location.replace("/order/detail/'.$order_no.'")</script>');
        }
    }

    /**
     * @purpose 微信支付同步回调
     * @param Request $request
     */
    public function wechatPayH5Sync (Request $request) {
        $order_no = $request->get('order_no');
        return view(
            '',
            [
                'orderNo' => $order_no
            ]
        );
    }
    /**
     * @purpose 微信充值支付同步回调
     * @param Request $request
     */
    public function wechatPayRechargeH5Sync (Request $request) {
        $order_no = $request->get('order_no');
        return view(
            '',
            [
                'orderNo' => $order_no
            ]
        );
    }
    /**
     * @purpose 检测微信扫码是否支付成功
     * @param Request $request
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\HttpException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function checkWechatPay(Request $request)
    {
        $order_no       = $request->get('order_no');
        return \app\activity\logic\PayNotify::paySync($order_no);
    }
    /**
     * @param Request $request
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @throws \Exception
     */
    public function pay (Request $request)
    {
        $order_no       = $request->get('order_no');
        $pay_method     = $request->get('pay_method');
        if (!$order_no || !$pay_method) {
            return Functions::result(
                STATUS_CODE::PARAMETER_ERROR,
                '参数错误'
            );
        }
        $order        = new ActivityOrder();
        $member       = new \app\model\Member();
        $order_attach = new ActivityOrderAttach();
        $order->startTrans();
        // 获取订单信息
        $order_info = $order
            ->with(['activity' => function ($query) {
                $query->field('id,title');
            }])
            ->where([
                ['order_no', '=', $order_no]
            ])
            ->lock(true)
            ->field('id,activity_id,uid,group_stage_id,status,order_no,create_at')
            ->find();
        if (!$order_info) {
            $order->rollback();
            return Functions::result(
                STATUS_CODE::FAIL,
                '订单不存在...!'
            );
        }
        if ($order_info->status !== 1) {
            $order->rollback();
            return Functions::result(
                STATUS_CODE::FAIL,
                '订单状态错误'
            );
        }
        $member_info = $member
            ->with('wechat')
            ->where('uid', $order_info->uid)
            ->find();
        // 获取支付金额
        $total_price = $order_attach
            ->where([
                ['order_id', '=', $order_info->id],
                ['status', '=', 1],
            ])
            ->sum('price');

        $voucher = $order_info->order_no.'-'.Functions::random(4);
        RE_VOUCHER:
        $voucher = $voucher = $order_info->order_no.'-'.Functions::random(4);
        if ($order->where(['pay_voucher' => $voucher])->count(1) > 0) {
            goto RE_VOUCHER;
        }
        $order->isUpdate(true)->save(['pay_voucher' => $voucher], ['id' => $order_info->id]);
        switch ($pay_method) {
            case 1: // 微信支付
                $is_wap              = Functions::isMobile();
                $app                 = Factory::payment(config('wechat.payment.official_account'));
                $data                = [
                    'body'         => '欢乐中国网-活动报名!',
                    'trade_type'   => $is_wap ? 'MWEB' : 'NATIVE',
                    'out_trade_no' => $voucher,
                    'total_fee'    => $total_price,
                    'notify_url' => config('wechat.payment.official_account.notify_url'),
                    'attach'       => $member_info->uuid
                ];

                $result              = $app->order->unify($data);
                if ($is_wap) {
                    header('location: '. $result['mweb_url'].'&redirect_url='.urlencode('http://server.enjoychina.cc/activity-api/activity.h5.wechat.sync?order_no='.$order_info->order_no));
                    die();
                }
                $qr_code = new QrCode($result['code_url']);
                $qr_code->setWriterByName('png');
                $qr_code->setEncoding('UTF-8');
//                $qr_code->setErrorCorrectionLevel('high');
                $data = $qr_code->writeString();
                $data = 'data:image/png;base64,' . base64_encode($data);
                $order->commit();
                return view(
                    '',
                    [
                        'code' => $data,
                        'title' => $order_info->activity->title,
                        'orderNo' => $order_info->order_no
                    ]
                );
            case 2: // 支付宝支付
                // 支付宝支付
                include Env::get('root_path'). 'extend/alipay/AopSdk.php';
                include Env::get('root_path'). 'extend/alipay/aop/request/AlipayTradeAppPayRequest.php';
                $aop                            = new \AopClient();
                $aop->gatewayUrl                = 'https://openapi.alipay.com/gateway.do';
                $aop->appId                     = config('alipay.app.appid');
                $aop->rsaPrivateKey             = config('alipay.app.private_key');
                $aop->format                    = "json";
                $aop->charset                   = "UTF-8";
                $aop->signType                  = "RSA";
                $aop->alipayrsaPublicKey        = config('alipay.app.public_key');
                $content                        = [];
                $content['body']                = '欢乐中国网活动报名';
                $content['subject']             = '参加活动【'.$order_info->activity->title.'】';
                $content['out_trade_no']        = $order_info->order_no;
                $content['timeout_express']     = '30m';
                $content['total_amount']        = $total_price / 100;
                $content['product_code']        = 'FAST_INSTANT_TRADE_PAY';
                $request                        = new \AlipayTradePagePayRequest();
                $request->setNotifyUrl('http://server.enjoychina.cc/activity-api/activity.activity.alipay.notify.async');
                $request->setReturnUrl('http://h5.enjoychina.cc/activity-api/activity.h5.alipay.sync');
                $request->setBizContent(json_encode($content));
                $response                       = $aop->pageExecute($request);
                die($response);
                break;
            case 3: // 余额支付
                if ($member_info->balance < $total_price) {
                    exit('<script>alert("余额不足");window.location.replace("/order/detail/'.$order_no.'")</script>');
                }
                $balance_result = $member
                    ->where('uid', $member_info->uid)
                    ->setDec('balance', $total_price);

                $update_data               = [];
                $update_data['status']     = 99;
                $update_data['pay_time']   = time(); // strtotime($send_pay_date);
                $update_data['pay_money']  = $total_price;
                $update_data['pay_method'] = 10;
                // 更新订单状态
                $order_result = $order
                    ->isUpdate(true)
                    ->save($update_data, ['id' => $order_info->id]);
                // 更新订单附表状态
                $order_attach_result = $order_attach
                    ->isUpdate(true)
                    ->save(['status' => 99], ['order_id' => $order_info->id, 'status' => 1]);
                // 记录账户资金流水
                $account_capital_flow = AccountCapitalFlow::M()
                    ->data([
                        'uid'          => $member_info->uid,
                        'quota'        => $total_price,
                        'balance' => ($member_info->balance - $member_info->frozen) - $total_price,
                        'type'         => 2,
                        'descriptions' => '参加活动【' . $order_info->activity->title . '】',
                    ])
                    ->save();
                // 记录账单活动支付账单
                $bill_result = Bill::addToBill(
                    $member_info->uid,
                    1,
                    $order_no,
                    $total_price,
                    10,
                    '报名活动: 【' . $order_info->activity->title . '】'
                );
                if ($balance_result &&
                    $order_result &&
                    $order_attach_result &&
                    $account_capital_flow &&
                    $bill_result) {
                    $order->commit();
                    exit('<script>window.location.replace("/order/detail/'.$order_no.'")</script>');
                }
                exit('<script>alert("余额支付失败");window.location.replace("/order/detail/'.$order_no.'")</script>');
                break;
        }
    }
}